package com.xinsoft.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.common.exception.BDException;
import com.xinsoft.entity.dto.ExcelErrRowDTO;
import com.xinsoft.entity.dto.QuaCauseImportDTO;
import com.xinsoft.entity.dto.QuaCausePageParam;
import com.xinsoft.entity.po.QuaCause;
import com.xinsoft.service.QuaCauseService;
import com.xinsoft.mapper.QuaCauseMapper;
import com.xinsoft.service.SysFileHisService;
import com.xinsoft.utils.ExcelUtils;
import com.xinsoft.validator.ValidatorUtils;
import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author hsm
* @description 针对表【qua_cause(不良原因)】的数据库操作Service实现
* @createDate 2023-08-16 17:23:56
*/
@Service
public class QuaCauseServiceImpl extends ServiceImpl<QuaCauseMapper, QuaCause>
    implements QuaCauseService{


    @Resource
    private SysFileHisService sysFileHisService;
    
    @Override
    public IPage<QuaCause> findPageListByParam(QuaCausePageParam param) {
        //分页
        Page<QuaCause> page = new Page<QuaCause>(param.getCurrentPage(), param.getPageSize());
        QueryWrapper<QuaCause> queryWrapper = new QueryWrapper<>();
        //查询条件
        queryWrapper.like(StringUtils.isNotEmpty(param.getCauseName()),"cause_name", param.getCauseName());
        queryWrapper.orderByDesc("update_time");
        IPage<QuaCause> resultPage = this.baseMapper.selectPage(page, queryWrapper);
        //返回值
        return resultPage;
    }

    @Override
    public QuaCause addQuaCause(QuaCause quaCause) {
        // 名称和编号 验重

        // 判断名称是否重复
        QueryWrapper<QuaCause> nameQuery = new QueryWrapper<>();
        nameQuery.select("id");
        nameQuery.eq("cause_name",quaCause.getCauseName());
        List names = this.list(nameQuery);

        if(CollectionUtil.isNotEmpty(names)){
            throw new BDException("操作失败，工位名称重复！");
        }

        //判断编号否重复
        QueryWrapper<QuaCause> codeQuery = new QueryWrapper<>();
        codeQuery.select("id");
        codeQuery.eq("cause_code",quaCause.getCauseCode());
        List codes = this.list(codeQuery);
        if(CollectionUtil.isNotEmpty(codes)) {
            throw new BDException("操作失败，工位编号重复！");
        }
        save(quaCause);
        return quaCause;
    }

    @Override
    public QuaCause editQuaCause(QuaCause quaCause) {
        //判断编号否重复
        QueryWrapper<QuaCause> nameQuery = new QueryWrapper<>();
        nameQuery.select("id");
        nameQuery.eq("cause_name",quaCause.getCauseName());
        nameQuery.ne("id",quaCause.getId());
        List names = this.list(nameQuery);

        if(CollectionUtil.isNotEmpty(names)){
            throw new BDException("操作失败，不良原因重复！");
        }

        //判断客户社会信用统一码是否重复
        QueryWrapper<QuaCause> codeQuery = new QueryWrapper<>();
        codeQuery.select("id");
        codeQuery.eq("cause_name",quaCause.getCauseCode());
        codeQuery.ne("id",quaCause.getId());
        List codes = this.list(codeQuery);
        if(CollectionUtil.isNotEmpty(codes)) {
            throw new BDException("操作失败，不良原因编号重复！");
        }
        
        updateById(quaCause);
        return quaCause;
    }

    @Override
    public void del(List<Integer> ids) {
        this.removeByIds(ids);
    }

    @Override
    public QuaCause getQuaCause(Integer id) {
        QuaCause quaCause  = this.getById(id);

        return quaCause;
    }

    @Override
    public JSONObject importExcel(MultipartFile multipartFile, HttpServletResponse response) throws IOException {
        // 初始化错误行信息list，用来记录导入失败的rowNum
        List<ExcelErrRowDTO> errRowDOs = new ArrayList<>();

        // 对excel是否为空进行check
        if (multipartFile.isEmpty()) {
            throw new BDException("导入失败，请选择文件！");
        }

        //设置excel参数
        ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        List<QuaCauseImportDTO> quaCauseList;
        List<QuaCause> quaCauses = CollectionUtil.newArrayList();

        JSONObject result = new JSONObject();

        // 解析excel中的行，放到sysSupplierList中
        try {
            // 解析excel
            quaCauseList = ExcelImportUtil.importExcel(multipartFile.getInputStream(), QuaCauseImportDTO.class, params);
        } catch (Exception e) {
            throw new BDException("导入失败，文件内容解析错误！");
        }

        //取出excel和db中所有重复的name
        List<String> excelSupplierNames =quaCauseList.stream()
                .map(QuaCauseImportDTO::getCauseName)
                .collect(Collectors.toList()); // 获取excel中所有的name
        List<String> dbNames = this.getAllName();//获取系统中所有的name
        List<String> duplicateNames = new ArrayList<>(); // 存放存在重复的name，用于定位重复存放存在重复的name的行

        if (dbNames.size() > 0 && excelSupplierNames.size() > 0) {
            dbNames.addAll(excelSupplierNames);//合并
            duplicateNames = ExcelUtils.getDuplicateElements(dbNames);//取出存在重复的name
        }

        //取出excel和db中所有重复的code
        List<String> excelSupplierCodes =quaCauseList.stream()
                .map(QuaCauseImportDTO::getCauseCode)
                .collect(Collectors.toList()); // 获取excel中所有的username
        List<String> dbSupplierCodes = this.getAllCode();//获取系统中所有的code
        List<String> duplicateCodes = new ArrayList<>(); // 存放存在重复的code，用于定位重复存放存在重复的code的行

        if (dbSupplierCodes.size() > 0 && excelSupplierCodes.size() > 0) {
            dbSupplierCodes.addAll(excelSupplierCodes);//合并
            duplicateCodes = ExcelUtils.getDuplicateElements(dbSupplierCodes);//取出存在重复的username
        }

        //校验
        if (quaCauseList.size() > 0) {

            int index = 1;
            for (QuaCauseImportDTO quaCauseDTO :quaCauseList) {
                index ++;
                // check
                StringBuilder stringBuilder = new StringBuilder();
                ExcelErrRowDTO excelErrRowDO= new ExcelErrRowDTO();

                // 参数校验
                stringBuilder.append(ValidatorUtils.validateExcel(quaCauseDTO));

                // 检验supplierName 是否重复
                if(duplicateNames.contains(quaCauseDTO.getCauseName())){
                    stringBuilder.append("名称已经存在，请勿重复！");
                }
                // 检验supplierCode 是否重复
                if(duplicateCodes.contains(quaCauseDTO.getCauseCode())){
                    stringBuilder.append("编号已经存在，请勿重复！");
                }

                // 将错误行信息保存到list
                String errMsg = stringBuilder.toString();
                if(StringUtils.isNotEmpty(errMsg)){
                    excelErrRowDO.setRowIndex(index);
                    excelErrRowDO.setErrMessage(errMsg);
                    errRowDOs.add(excelErrRowDO);
                    continue;
                }
                //保存
                QuaCause quaCause = new QuaCause();
                BeanUtils.copyProperties(quaCauseDTO,quaCause);
               quaCauses.add(quaCause);
            }
            saveBatch(quaCauses);

            // 导出错误行
            String errFileUrl = ExcelUtils.exportErrRows(errRowDOs,multipartFile,sysFileHisService);
            result.put("errFileUrl",errFileUrl);
        }
        return result;
    }


    private List<String> getAllCode() {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("cause_code");
        List<QuaCause> userList = this.list();
        List<String> codes = userList.stream().map(QuaCause::getCauseCode).collect(Collectors.toList());
        return codes;
    }

    private List<String> getAllName() {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("cause_name");
        List<QuaCause> userList = this.list();
        List<String> names = userList.stream().map(QuaCause::getCauseName).collect(Collectors.toList());
        return names;
    }
}




